package com.nmgydy.util;

import java.io.Serializable;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Component;

@Component
public class HibernateDao {

	@Resource
	private SessionFactory sessionFactory;

	/**
	 * 获得列表
	 * @return 	list 列表
	 * */
	public List<?> list(String hql) {
		Session session = null;
		List<?> list = new ArrayList<Object>();
		try {
			session = sessionFactory.openSession();
			list = (List<?>) session.createQuery(hql).list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}

	/**
	 * 获得分页列表
	 * */
	public List<?> list(String hql, int page, int pageSize) {
		Session session = null;
		List<?> list = new ArrayList<Object>();
		try {
			session = sessionFactory.openSession();
			list = (List<?>) session.createQuery(hql).setFirstResult((page - 1) * pageSize).setMaxResults(pageSize).list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}

	/**
	 * 获得列表
	 * @param hql		查询语句
	 * @param params	参数列表
	 * @return list		列表
	 * */
	public List<?> list(String hql, Map<String, Object> params) {
		Session session = null;
		List<?> list = new ArrayList<Object>();
		try {
			session = sessionFactory.openSession();
			Query q = session.createQuery(hql);
			setParams(q,params);
			list = (List<?>) q.list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}
	
	/**
	 * 获得分页列表
	 * */
	public List<?> list(String hql, Map<String, Object> params, int page, int pageSize) {
		Session session = null;
		List<?> list = new ArrayList<Object>();
		try {
			session = sessionFactory.openSession();
			Query q = session.createQuery(hql);
			setParams(q,params);
			list = q.setFirstResult((page - 1) * pageSize).setMaxResults(pageSize).list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}

	/**
	 * 获得范围列表
	 * */
	public List<?> rangeList( String hql, Map<String, Object> params, int start, int number) {
		Session session = null;
		List<?> list = new ArrayList<Object>();
		try {
			session = sessionFactory.openSession();
			Query q = session.createQuery(hql);
			setParams(q,params);
			list = q.setFirstResult(start).setMaxResults(number).list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}

	/**
	 * 通过id加载实例信息
	 * @param id		查询id
	 * @return 
	 * @return Object	实例信息实例
	 * @throws Exception
	 * */
	@SuppressWarnings("unchecked")
	public <T> T load(Class<T> c, Serializable id){
		T object = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			object = (T) session.get(c, id);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return object;
	}


	/**
	 * 保存实例
	 * */
	public boolean save(Object object){
		Session session = null;
		Transaction transaction = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			session.save(object);
			transaction.commit();
		} catch (Exception e) {
			if (transaction != null) {
				transaction.rollback();
			}
			e.printStackTrace();
			return false;
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return true;
	}

	/**
	 * 更新实例信息
	 * */
	public boolean update( Object object){
		Session session = null;
		Transaction transaction = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			session.update(object);
			transaction.commit();
		} catch (Exception e) {
			if (transaction != null) {
				transaction.rollback();
			}
			e.printStackTrace();
			return false;
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return true;
	}

	/**
	 * 删除实例信息
	 * */
	public boolean delete(Object object){
		Session session = null;
		Transaction transaction = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			session.delete(object);
			transaction.commit();
		} catch (Exception e) {
			if (transaction != null) {
				transaction.rollback();
			}
			e.printStackTrace();
			return false;
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return true;
	}

	/**
	 * 通过ID删除
	 * @param entityName
	 * @param id
	 * */
	public boolean delete(String entityName,String id) {
		Session session = null;
		Transaction transaction = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			session.createQuery("delete from "+entityName+" where id='"+id+"'")
			.executeUpdate();
			transaction.commit();
		} catch (Exception e) {
			if (transaction != null) {
				transaction.rollback();
			}
			e.printStackTrace();
			return false;
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return true;
	}

	/**
	 * 统计总数
	 * @return boolean	存在与否
	 * */
	public long count(String tableName) {
		Session session = null;
		long count = 0;
		try {
			session = sessionFactory.openSession();
			String hql = "select count(*) from " + tableName;
			count = (Long) session.createQuery(hql).uniqueResult();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return count;
	}

	/**
	 * 带条件统计
	 * @param hql		查询语句
	 * @param params	参数列表
	 * @return boolean	存在与否
	 * */
	public long count(String hql, Map<String, Object> params) {
		Session session = null;
		long count = 0;
		try {
			session = sessionFactory.openSession();
			hql = hql.substring(hql.indexOf("from"));
			hql = "select count(*) " + hql;
			Query q = session.createQuery(hql);
			setParams(q,params);
			count = (Long) q.uniqueResult();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return count;
	}

	/**
	 * 执行查询
	 * @param hql		查询语句
	 * @return list		列表
	 * */
	public int executeUpdate(String hql){
		return executeUpdate(hql,new HashMap<String, Object>());
	}
	/**
	 * 执行查询
	 * @param hql		查询语句
	 * @param params	参数列表
	 * @return list		列表
	 * */
	public int executeUpdate(String hql, Map<String, Object> params) {
		Session session = null;
		Transaction transaction = null;
		int rows=0;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			Query q = session.createQuery(hql);
			setParams(q,params);
			rows = q.executeUpdate();
			transaction.commit();
		} catch (Exception e) {
			if (transaction != null) {
				transaction.rollback();
			}
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return rows;
	}

	/** 获得SessionFactory */
	public SessionFactory getSessionFactory(){
		return sessionFactory;
	}
	
	/** 设置参数 */
	private void setParams(Query query,Map<String, Object> params){
		for (String key : params.keySet()) {
			Object value = params.get(key);
			if(value instanceof Collection<?>){  
				query.setParameterList(key, (Collection<?>)value);  
            }else if(value instanceof Object[]){  
            	query.setParameterList(key, (Object[])value);  
            }else{  
            	query.setParameter(key, value);  
            }
		}
	}
	
	public List<?> sqlList(String sql, Map<String,Object> params) {
		Session session = null;
		List<?> list = new ArrayList<Object>();
		try {
			session = sessionFactory.openSession();
			Query q = session.createSQLQuery(sql);
			setParams(q,params);
			list = (List<?>) q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return list;
	}
	
	public List<?> sqlList(String sql) {
		return sqlList(sql, null);
	}
	
	public List<?> sqlList(String sql, Map<String,Object> params, int page, int pageSize) {
		sql = sql+" limit "+(page*pageSize)+","+(page*pageSize+pageSize);
		return sqlList(sql, params);
	}
	
	public Long sqlCount(String sql, List<Object> params) {
		Session session = null;
		long count=0;
		try {
			session = sessionFactory.openSession();
			Query q = session.createSQLQuery("select count(*) "+sql);
			if(params != null){
				for(int i=0;i<params.size();i++){
					q.setParameter(i, params.get(i));
				}
			}
			count = ((BigInteger) q.uniqueResult()).longValue();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return count;
	}
	
}
